/**
  ************************************* Copyright ******************************
  * FileName   : list.c
  * Version    : v1.0
  * Author     : yychao
  * Date       : 2023-12-14
  * Description:
  * Function List:
  	1. ....
  	   <version>:
  <modify staff>:
  		  <data>:
   <description>:
  	2. ...
  ******************************************************************************
 */

#include "list.h"
#include <stdio.h>
#include "heaplib.h"
#include "log.h"
#include <assert.h>


void assert_failed(const uint8_t* expr, const uint8_t* file, uint32_t line)
{
    while (1)
    {
    }
}

ListNode* BuyNode(LTDataType x)
{
    ListNode* node = (ListNode*)sys_malloc(sizeof(ListNode));
    if (node == NULL)
    {
        LOG_ERROR("sys_malloc fail");
        return node;
    }

    node->_data = x;
    node->_next = NULL;
    node->_prev = NULL;

    return node;
}

ListNode* ListCreate()
{
    ListNode* node = (ListNode*)sys_malloc(sizeof(ListNode));
    if (!node)
    {
        LOG_ERROR("sys_malloc fail:");
        return NULL;
    }

    node->_next = node;
    node->_prev = node;

    return node;
}

void ListDestory(ListNode* pHead)
{
    ListNode* cur = pHead->_next;
    while (cur != pHead)
    {
        ListNode* tmp = cur->_next;
        sys_free(cur);
        cur = tmp;
    }

    sys_free(pHead);
}

void ListPrint(ListNode* pHead)
{
#if 0
    ListNode* cur = pHead->_next;
    LOG_INFO("pHead-");
    while (cur != pHead)
    {
        LOG_INFO("(%d,%d)-", cur->_data.x, cur->_data.y);
        cur = cur->_next;
    }
    LOG_INFO("\r\n");
#endif
}

void ListPushBack(ListNode* pHead, LTDataType x)
{

    //ListInsert(pHead, x);
    ListNode* newnode = BuyNode(x);

    pHead->_prev->_next = newnode;
    newnode->_prev=pHead->_prev;
    newnode->_next = pHead;
    pHead->_prev = newnode;
}

void ListPopBack(ListNode* pHead)
{

    //ListErase(pHead->_prev);
    if (pHead->_prev != pHead)
    {
        ListNode* tmp = pHead->_prev;
        pHead->_prev = tmp->_prev;
        tmp->_prev->_next = pHead;
        sys_free(tmp);
        tmp = NULL;
    }
}

void ListPushFront(ListNode* pHead, LTDataType x)
{

    //ListInsert(pHead->_next, x);
    ListNode* newnode = BuyNode(x);
    newnode->_next=pHead->_next;
    newnode->_prev = pHead;
    pHead->_next->_prev = newnode;
    pHead->_next = newnode;
}

void ListPopFront(ListNode* pHead)
{

    //ListErase(pHead->_next);
    if (pHead->_next != pHead)
    {
        ListNode* node = pHead->_next;
        node->_next->_prev = pHead;
        pHead->_next = node->_next;
        sys_free(node);
        node = NULL;
    }
}

ListNode* ListFind(ListNode* pHead, LTDataType x)
{


    ListNode* cur = pHead->_next;
    while (cur != pHead)
    {

        if (memcmp(&cur->_data, &x, sizeof(LTDataType)) == 0)
            return cur;
        cur = cur->_next;
    }

    return NULL;

}

void ListInsert(ListNode* pos, LTDataType x)
{


    ListNode* newnode = BuyNode(x);
    ListNode* dist = pos->_prev;

    dist->_next = newnode;
    newnode->_prev = dist;
    newnode->_next = pos;
    pos->_prev = newnode;

}

void ListErase(ListNode* pos)
{


    ListNode* posPrev = pos->_prev;
    ListNode* posNext = pos->_next;

    posPrev->_next = posNext;
    posNext->_prev = posPrev;
    sys_free(pos);
}

